trait IFactory {
    fn make_shoe(&self) -> Box<dyn IShoe>;
    fn make_shirt(&self) -> Box<dyn IShirt>;
}

trait IShoe {
    fn name(&self) -> String;
    fn size(&self) -> i32;
}

trait IShirt {
    fn name(&self) -> String;
    fn logo(&self) -> String;
}


//==========
struct StarShoe {
    name: String,
    size: i32,
}

struct StarShirt {
    name: String,
    logo: String,
}

impl IShoe for StarShoe {
    fn name(&self) -> String {
        String::from("name: StarShoe")
    }
    fn size(&self) -> i32 {
        41
    }
}

impl IShirt for StarShirt {
    fn name(&self) -> String {
        String::from("name: StarShirt")
    }
    fn logo(&self) -> String {
        String::from("logo StarShirt")
    }
}

//=========
struct Factory {}

impl IFactory for Factory {
    fn make_shirt(&self) -> Box<dyn IShirt> {
        Box::new(StarShirt {
            name: String::from("star"),
            logo: String::from("star"),
        })
    }
    fn make_shoe(&self) -> Box<dyn IShoe> {
        Box::new(StarShoe {
            name: String::from("star"),
            size: 42,
        })
    }
}


#[test]
fn main() {
    let factory = Factory {};
    println!("{:#?}", factory.make_shoe().name());
    println!("{:#?}", factory.make_shirt().name());
}
